#include <iostream>
#include <vector>
#include <iomanip>

using namespace std;

typedef enum
{
    REQUEST_PACKET_ID = 0x01,
    RESPONSE_PACKET_ID = 0x07,
    DATA1_PACKET_ID = 0x02,
    DATA2_PACKET_ID = 0x08, // 结尾数据包
} packet_id_t;

struct Protocol_Data
{
    uint16_t packetHead{0xEF01};
    uint32_t deviceAddr{0xFFFFFFFF};
    packet_id_t packetid;
    uint16_t packetLength;
    std::vector<uint8_t> payload; // 载荷[指令码+参数]
    uint16_t checkSum;

    void Fp_DataFormat(Protocol_Data *pro_data,const packet_id_t packetid,vector<uint8_t> num)
    {

        pro_data->packetid = packetid;

        pro_data->payload.insert(pro_data->payload.end(), num.begin(), num.end());
        // 计算包长度
        pro_data->packetLength = 2+payload.size(); // 2字节的校验和 + 载荷长度
        
        // 计算校验和
        pro_data->checkSum = pro_data->packetid;

        pro_data->checkSum += (pro_data->packetLength >> 8 & 0xff);
        pro_data->checkSum += (pro_data->packetLength & 0xff);

        for (auto item : pro_data->payload)
        {
            pro_data->checkSum += item;
        }
    }
};

class Fp_protocol
{

public:
    Fp_protocol();
    // 初始化指纹协议
    void FProtocol_init();
    // 打印协议
    void Dis_protocol();

    // 生成握手协议
    static Fp_protocol HS_Protocol();
    // 自动验证指纹
    static Fp_protocol Auto_Identify(uint16_t id, uint16_t params);
    // 删除模板协议
    static Fp_protocol Delete_Protocol(const uint16_t pageId, const uint16_t delCount = 200);
    // 擦除指纹库协议
    static Fp_protocol Erase_FProtocol();
    // 读取有效模板的个数协议
    static Fp_protocol Valid_NumsProtocol();
    // 获取图像协议
    static Fp_protocol GetImage_Protocol();
    // 注册用获取图像协议
    static Fp_protocol Acquire_ImageProtocol();
    // 生成指纹特征码的协议
    static Fp_protocol Feature_Protocol(uint8_t bufId);
    // 合成模板的协议
    static Fp_protocol Template_Protocol();

    // 存储模板的协议
    static Fp_protocol Store_Protocol(uint16_t pageId, uint8_t bufId = 1);
    // 搜索模板协议
    static Fp_protocol Search_Protocol(uint8_t bufId, uint16_t start = 0, uint16_t pages = 500);

    // 根据应答包生成应答协议
    static Fp_protocol Acknow_Protocol(std::vector<uint8_t> packetData);

    // 获取协议
    static vector<uint8_t> *Get_vector() { return &fp_vector; }

    // 判断接收的数据包是否正确
    bool isValidPacketData();

    // 确认操作是否成功，判断确认码是否是 0x00
    bool verifyOperationResult();

 
    Protocol_Data pro_data;
private:
    void addPacketHead();
    void addDeviceAddr();
    void addPacketLength();
    void addPacketId();
    void addPayload();
    void addCheckSum();

    
    // 存放指令码
    static std::vector<uint8_t> fp_vector;
};
